Supabase Edge Functions 시스템
1. Supabase Edge Functions의 이해
1.1 Edge Functions 정의 및 핵심 가치 제안
Supabase Edge Functions는 Supabase 플랫폼이 제공하는 서버리스 컴퓨팅 기능으로, 서버사이드 로직을 담은 TypeScript 함수를 전 세계에 분산된 엣지(Edge) 네트워크에 배포하는 시스템을 지칭한다.1 이 시스템의 핵심적인 가치 제안은 지리적으로 사용자와 가장 가까운 위치에서 코드를 실행함으로써 API 요청에 대한 물리적 거리를 단축하고 네트워크 지연 시간(latency)을 최소화하는 데 있다.1 결과적으로, 최종 사용자는 더 빠른 애플리케이션 응답 속도를 경험하게 되며, 이는 전반적인 사용자 경험(UX) 향상으로 이어진다.
함수는 Deno 런타임을 기반으로 개발되며, 이는 TypeScript를 네이티브로 지원하고 강력한 보안 모델을 제공하는 현대적인 JavaScript/TypeScript 런타임 환경이다.2 Edge Functions는 완전 관리형(Fully managed) 서비스 형태로 제공되므로, 개발자는 서버 프로비저닝, 스케일링, 유지보수와 같은 인프라 관리 부담에서 벗어나 비즈니스 로직 개발에만 집중할 수 있다.5 트래픽 변동에 따라 함수는 자동으로 확장 및 축소되어 안정적인 서비스 운영을 보장한다. 이러한 특성 덕분에 Edge Functions는 Stripe 결제 이벤트 처리와 같은 웹훅(Webhook) 수신이나 외부 서드파티(3rd-party) 서비스와의 연동 로직을 구현하는 데 매우 효과적이다.2
그러나 Supabase Edge Functions의 진정한 전략적 가치는 단순히 ’낮은 지연 시간’에만 국한되지 않는다. Supabase 생태계의 다른 구성 요소들과의 ’긴밀하게 통합된 낮은 지연 시간’을 제공한다는 점에서 차별화된다. 다른 경쟁 엣지 컴퓨팅 서비스가 원시적인 성능 우위를 제공할 수 있지만, Supabase는 자사의 BaaS(Backend as a Service) 제품군을 위한 프로그래밍 가능한 미들웨어 계층으로서의 함수를 제공한다. 이는 개발자가 별도의 인증, 데이터베이스 연결, 스토리지 접근 로직을 복잡하게 구성할 필요 없이, 사전 통합된 환경에서 즉시 백엔드 로직을 확장할 수 있게 해준다. 따라서 개발자는 순수한 네트워크 속도 개선 효과뿐만 아니라, 개발 생산성의 극적인 향상이라는 더 큰 가치를 얻게 된다. 이는 Edge Functions를 범용 서버리스 플랫폼이라기보다는 ’BaaS 확장 도구’로 포지셔닝하는 Supabase의 핵심 전략을 보여준다.
1.2 Supabase 생태계 내에서의 역할
Edge Functions는 독립적인 기능으로 존재하기보다는, Supabase의 핵심 서비스인 데이터베이스(Postgres), 인증(Auth), 스토리지(Storage)와 유기적으로 결합하여 하나의 완성된 백엔드 시스템을 구축하는 데 있어 ’접착제(glue)’와 같은 중추적인 역할을 수행한다.5 예를 들어, 새로운 사용자가 가입(Auth)하면 Edge Function을 트리거하여 환영 이메일을 보내고, 해당 사용자의 프로필 데이터를 데이터베이스(Database)에 생성하며, 기본 프로필 이미지를 스토리지(Storage)에 업로드하는 일련의 워크플로우를 자동화할 수 있다.
이러한 통합은 개발 패러다임에 중요한 변화를 가져온다. 전통적으로 백엔드 서버를 구축하기 위해 AWS EC2, RDS, S3와 같은 개별 클라우드 서비스를 조합하고 네트워킹, 보안, 배포 파이프라인을 직접 설정해야 했던 복잡한 과정이 Supabase 생태계 안에서는 대폭 단순화된다.6 Edge Functions는 이러한 복잡성을 추상화하여, 개발자가 간단한 프로젝트부터 수백만 사용자를 대상으로 확장 가능한 복잡한 애플리케이션에 이르기까지, 비용 효율적이고 편리하게 서버사이드 로직을 구현하고 확장할 수 있는 강력한 수단을 제공한다. 이는 특히 소규모 팀이나 빠른 프로토타이핑이 중요한 프로젝트에서 기존 클라우드 인프라 구축 방식에 대한 매력적인 대안이 된다.
2. 기술 아키텍처 심층 분석
2.1 Deno 런타임: Node.js를 넘어선 선택
Supabase는 Edge Functions의 실행 환경으로 널리 사용되는 Node.js 대신 Deno를 채택했다.2 이는 Deno가 제공하는 여러 가지 현대적인 아키텍처상의 이점을 전략적으로 활용하기 위한 결정이다. Deno는 Node.js의 창시자인 라이언 달(Ryan Dahl)이 Node.js의 설계상 한계를 극복하기 위해 새롭게 만든 런타임으로, 보안, 개발 편의성, 표준 준수 측면에서 진일보한 특징을 가진다.
첫째, 보안 모델이다. Deno의 가장 핵심적인 철학은 ‘기본적으로 안전한(Secure by default)’ 실행 환경을 제공하는 것이다.7 Deno로 실행되는 코드는 기본적으로 샌드박스(sandbox) 내에서 동작하며, 파일 시스템 접근, 네트워크 연결, 환경 변수 조회와 같은 민감한 작업에 대한 권한을 가지고 있지 않다. 이러한 기능에 접근하기 위해서는 개발자가 실행 시점에 --allow-read, --allow-net과 같은 플래그를 통해 명시적으로 권한을 부여해야 한다.7 이는 의존성 패키지가 무분별하게 시스템 자원에 접근하여 발생할 수 있는 잠재적인 공급망 공격(supply chain attacks)의 위험을 원천적으로 차단하는 강력한 방어 메커니즘으로 작용한다.9
둘째, TypeScript 우선 지원이다. Deno는 별도의 트랜스파일러나 복잡한 설정 과정 없이 TypeScript를 네이티브하게 지원한다.3 이는 개발자가 정적 타입 검사를 통해 코드의 안정성을 높이고, 최신 언어 기능을 활용하여 생산성을 극대화할 수 있도록 돕는다. Supabase가 TypeScript를 주요 개발 언어로 장려하는 만큼, Deno의 이러한 특성은 Supabase 생태계의 개발 경험과 완벽하게 부합한다.
셋째, 이식성 및 개방성이다. Deno는 특정 기업에 종속되지 않은 오픈 소스 프로젝트이며, 웹 표준을 적극적으로 준수한다.4 Supabase Edge Functions는 로컬 개발 환경뿐만 아니라, Deno와 호환되는 모든 플랫폼, 심지어 개발자가 직접 구축한 자체 호스팅 인프라에서도 동일하게 실행될 수 있다.4 이는 개발자가 Supabase 플랫폼에 종속될 위험(vendor lock-in)을 줄여주며, 필요에 따라 자유롭게 인프라를 이전할 수 있는 유연성을 제공한다.
마지막으로, WebAssembly (WASM) 지원이다. Deno는 WASM 모듈을 직접 가져와 실행할 수 있는 기능을 내장하고 있다.4 이를 통해 이미지 처리, 비디오 인코딩, 암호화와 같이 CPU 집약적인 고성능 컴퓨팅 작업을 JavaScript의 성능 한계를 넘어 네이티브에 가까운 속도로 처리할 수 있는 가능성을 열어준다.
2.2 V8 Isolate 기반 실행 모델
Deno 런타임의 핵심에는 Google이 Chrome 브라우저를 위해 개발한 고성능 JavaScript 및 WebAssembly 엔진인 V8이 자리 잡고 있다.11 Supabase Edge Functions는 V8의 실행 단위인 V8 Isolate를 활용하여 사용자 코드를 격리하고 실행한다.12
V8 Isolate는 완전히 분리된 메모리 힙(heap)과 독립적인 실행 상태를 가지는 V8 엔진의 경량 인스턴스다.11 이는 운영체제 수준의 가상화 기술인 가상 머신(VM)이나 컨테이너(Container)와 비교했을 때, 훨씬 적은 리소스를 사용하며 수 밀리초(ms) 내에 시작할 수 있다는 압도적인 장점을 가진다.14 V8 Isolate의 개념을 이해하는 가장 쉬운 비유는 웹 브라우저의 탭 모델이다. 각 브라우저 탭은 독립적인 웹 페이지를 렌더링하고 JavaScript를 실행하지만, 한 탭의 코드가 다른 탭의 코드나 데이터에 직접 접근할 수는 없다. 이와 마찬가지로, 각 탭은 자신만의 V8 Isolate 내에서 안전하게 실행된다.12
이러한 Isolate 기반 실행 모델은 서버리스 환경, 특히 다수의 사용자가 코드를 실행하는 멀티테넌트(multi-tenant) 환경에서 두 가지 핵심적인 우위를 제공한다. 첫째는 성능이다. 전통적인 서버리스 플랫폼의 고질적인 문제였던 콜드 스타트(cold start) 현상을 거의 없앨 수 있다. VM이나 컨테이너가 부팅되는 데 수백 ms에서 수 초가 걸리는 반면, Isolate는 거의 즉시 시작되므로 요청이 들어왔을 때 지연 없이 코드를 실행할 수 있다. 둘째는 보안이다. 각 Isolate는 메모리 공간이 완벽하게 분리되어 있기 때문에, 한 사용자의 함수가 악의적인 코드를 실행하더라도 다른 사용자의 함수나 호스트 시스템에 영향을 미칠 수 없다.12 이 강력한 격리 기능 덕분에 Supabase는 수많은 고객의 신뢰할 수 없는 코드를 동일한 물리적 서버에서 안전하게 실행할 수 있다.
2.3 edge-runtime 아키텍처 분석
Supabase는 Deno 런타임을 기반으로 edge-runtime이라는 자체 웹 서버를 구축하여 Edge Functions를 호스팅하고 실행한다.15 이 edge-runtime은 오픈 소스로 공개되어 있으며, 로컬 개발 환경에서 supabase functions serve 명령을 실행할 때와 프로덕션 환경에서 함수를 실행할 때 동일한 런타임이 사용된다. 이는 개발 환경과 운영 환경 간의 차이로 인해 발생할 수 있는 예기치 않은 문제를 최소화하고, 일관된 개발 경험을 보장하는 중요한 요소다.5
edge-runtime의 아키텍처는 의도적으로 두 개의 런타임으로 분리되어 설계되었다. 이는 단순한 구현상의 디테일이 아니라, 멀티테넌시 환경의 보안을 강화하기 위한 전형적인 ‘권한 분리(privilege separation)’ 보안 패턴을 적용한 것이다. 이 구조는 신뢰할 수 있는 고권한의 감독관(Main Runtime)이 요청을 검증하고 리소스를 할당하며, 신뢰할 수 없는 저권한의 샌드박스(User Runtime)가 실제 사용자 코드를 실행하는 방식으로 동작한다.
- Main Runtime: 이 런타임은 사용자 런타임으로 요청을 전달하는 프록시(proxy) 역할을 담당한다. 모든 요청의 진입점으로서, 사용자 함수가 실행되기 전에 인증(authentication), 라우팅(routing), 로깅과 같은 사전 처리 작업을 수행한다. Main Runtime은
service_role_key와 같은 모든 환경 변수에 접근할 수 있는 높은 권한을 가지며, 메모리나 실행 시간과 같은 사용자 대상 리소스 제한이 적용되지 않는다.15 즉, 시스템의 신뢰 경계(trust boundary) 내에 있는 특권 프로세스다. - User Runtime: 이 런타임은 Main Runtime으로부터 전달받은 요청을 바탕으로 실제 사용자가 작성한 코드를 실행하는 인스턴스다. 이 환경은 매우 제한적이다. 메모리 사용량(256MB), CPU 시간(2초), 전체 실행 시간(400초) 등 엄격한 리소스 제한이 적용된다. 또한, 보안을 위해 Main Runtime이 명시적으로 허용한 환경 변수(예:
SUPABASE_URL,SUPABASE_ANON_KEY)에만 접근할 수 있다.15 이처럼 User Runtime은 V8 Isolate의 샌드박스 위에서 다시 한번 운영체제 수준의 제약을 받는, 강력하게 격리된 실행 환경이다.
이러한 권한 분리 아키텍처는 서버리스 플랫폼이 직면하는 가장 큰 과제, 즉 수많은 고객의 임의적이고 신뢰할 수 없는 코드를 공유 인프라에서 안전하게 실행하는 문제를 해결하는 핵심적인 설계다. 신뢰할 수 있는 중재자(Main Runtime)를 코드 실행 환경(User Runtime) 앞에 배치함으로써, Supabase는 사용자 코드가 실행되기 전에 보안 정책을 강제하고, 시크릿을 관리하며, 리소스 제한을 적용할 수 있다. 이는 V8 Isolate의 샌드박스 모델을 상용 멀티테넌트 제품으로 만드는 데 필수적인 구조이며, 전체 Edge Functions 플랫폼의 보안과 안정성은 Main Runtime의 견고함에 크게 의존하게 된다.
2.4 Deno 보안 모델 심층 탐구
Deno의 보안 모델은 앞서 언급했듯이 명시적인 **권한 부여 시스템(permission system)**에 기반한다.7
deno run 명령어를 통해 스크립트를 실행할 때, 개발자는 --allow-net (네트워크 접근 허용), --allow-read (파일 시스템 읽기 허용), --allow-env (환경 변수 접근 허용)와 같은 플래그를 사용하여 해당 스크립트에 필요한 권한을 최소한으로 부여해야 한다. 만약 스크립트가 허용되지 않은 작업을 시도하면, Deno 런타임은 즉시 실행을 중단시키고 PermissionDenied 오류를 발생시킨다.
Supabase Edge Functions는 Deno의 파트너사인 Deno Deploy의 인프라 위에서 실행되며, 기본 Deno 런타임보다 한층 더 강화된 보안 제약을 적용한다.12 예를 들어, Supabase Edge Functions 환경에서는 파일 시스템에 대한 쓰기 권한이 원천적으로 차단되어 있어, 함수가 임의의 파일을 생성하거나 수정하는 행위가 불가능하다. 이는 함수가 호스트 시스템에 미칠 수 있는 잠재적인 부작용을 최소화하기 위한 중요한 보안 조치다.
그러나 Deno의 보안 모델이 완벽한 것은 아니다. 최근 발표된 학술 연구에 따르면, Deno의 권한 시스템에는 몇 가지 잠재적인 우회 경로가 존재한다.9 예를 들어, 개발자가 편의를 위해 --allow-read=.와 같이 현재 디렉토리 전체에 대한 읽기 권한을 광범위하게(coarse-grained) 부여할 경우, 공격자는 /proc/self/environ과 같은 운영체제 내부 파일을 읽어 환경 변수를 탈취할 수 있다. 또한, 쓰기 권한이 부여된 경우, .bashrc와 같은 OS 시작 스크립트를 수정하여 다음 시스템 부팅 시 임의의 코드를 실행하도록 만들 수도 있다.
이러한 연구 결과는 Deno의 보안 모델이 강력하지만, 개발자의 신중한 권한 관리에 크게 의존한다는 점을 시사한다. 즉, ’최소 권한의 원칙(Principle of Least Privilege)’을 철저히 준수하여 함수에 꼭 필요한 권한만 세분화하여(fine-grained) 부여하는 것이 공급망 공격으로부터 애플리케이션을 보호하는 데 필수적이다.
3. 개발 워크플로우 및 관리
3.1 개발 환경 구축
Supabase Edge Functions를 효율적으로 개발하기 위해서는 잘 구성된 로컬 개발 환경이 필수적이다. 핵심 구성 요소는 Supabase CLI, Docker, 그리고 Deno를 지원하는 코드 에디터다.
-
Supabase CLI: Edge Functions의 생성, 테스트, 배포, 관리 등 전체 생명주기를 관장하는 핵심 명령줄 도구다.
npm,brew등 다양한 패키지 관리자를 통해 설치할 수 있으며, 최신 기능을 사용하기 위해 주기적으로 업데이트하는 것이 권장된다.2 -
Docker: 로컬 환경에서 Supabase의 전체 스택, 즉 Postgres 데이터베이스, GoTrue 인증 서버, 스토리지 API 등을 컨테이너 형태로 실행하기 위해 필요하다.16
supabase start 명령을 실행하면 CLI가 자동으로 필요한 Docker 이미지를 다운로드하고 컨테이너를 실행하여 프로덕션과 거의 동일한 환경을 로컬에 구축해준다. 최근 CLI 버전에서는 Docker 없이 API를 통해 함수를 배포하는 --use-api 옵션이 추가되었지만, 로컬에서의 통합 테스트를 위해서는 여전히 Docker가 필수적이다.19
- VS Code 설정: Visual Studio Code는 Deno 개발에 가장 널리 사용되는 에디터다. Deno 공식 확장 프로그램(
denoland.vscode-deno)을 설치하면 타입 체크, 자동 완성, 포맷팅 등 강력한 IDE 지원을 받을 수 있다.2 최적의 개발 경험을 위해, 프로젝트 루트에.vscode/settings.json파일을 생성하고 다음과 같이 Deno 확장 프로그램을 활성화하고 함수 디렉토리를 지정하는 것이 좋다.21
{
"deno.enable": true,
"deno.lint": true,
"deno.unstable": true,
"deno.enablePaths": [
"supabase/functions"
]
}
3.2 함수 생명주기 관리 (CLI 중심)
Supabase CLI는 Edge Functions의 전체 생명주기를 관리하는 일관된 명령어 세트를 제공한다.
- 생성: 프로젝트 디렉토리 내에서
supabase functions new <function-name>명령어를 실행하면supabase/functions/<function-name>/index.ts경로에 기본적인 ‘Hello World’ 템플릿 코드가 생성된다.18 - 로컬 테스트: 먼저
supabase start명령으로 모든 로컬 Supabase 서비스를 실행해야 한다. 그 다음,supabase functions serve <function-name>명령을 실행하면 특정 함수를 위한 로컬 개발 서버가 시작된다. 이 서버는 코드 변경 사항을 감지하여 자동으로 함수를 재시작하는 핫 리로딩(hot-reloading) 기능을 지원하여 빠른 개발 주기를 가능하게 한다.5 - 로컬 호출: 함수가 로컬에서 실행되면, 기본적으로
http://localhost:54321/functions/v1/<function-name>주소로 접근할 수 있다.curl과 같은 도구를 사용하여 이 엔드포인트에 테스트 요청을 보낼 수 있다. 대부분의 경우,Authorization헤더에 로컬 개발용anon키를Bearer토큰으로 포함해야 한다. 이 키는supabase status명령으로 확인할 수 있다.16 - 배포: 함수 개발 및 테스트가 완료되면,
supabase login으로 Supabase 계정에 로그인하고supabase link --project-ref <project-id>명령으로 로컬 프로젝트를 원격 Supabase 프로젝트와 연결한다. 연결이 완료되면supabase functions deploy <function-name>명령을 통해 해당 함수를 프로덕션 환경에 배포할 수 있다. 특정 함수 이름 없이supabase functions deploy를 실행하면supabase/functions디렉토리 내의 모든 함수가 한 번에 배포된다.16 - 주요 배포 옵션:
--no-verify-jwt: 이 플래그를 사용하면 해당 함수에 대한 JWT 인증 검사를 비활성화한다. Stripe 웹훅과 같이 외부 서비스로부터 인증 정보 없이 호출되어야 하는 엔드포인트를 만들 때 유용하다. 하지만 누구나 이 함수를 호출할 수 있게 되므로, 민감한 로직에 사용하는 것은 매우 위험하다.18--env-file:supabase functions serve명령어와 함께 사용하여, 로컬 테스트 시 특정 환경 변수 파일을 로드하도록 지정할 수 있다. 이를 통해 여러 개발 환경에 대한 설정을 분리하여 관리할 수 있다.18--use-api: Docker 데몬이 실행 중이지 않은 환경(예: 일부 CI/CD 환경)에서도 함수를 배포할 수 있도록, Docker를 통하지 않고 Supabase Management API를 직접 사용하여 함수를 배포하는 옵션이다. 최신 CLI 버전에서는 이 방식이 기본값으로 고려되고 있다.18- 업데이트 및 삭제: 이미 배포된 함수의 코드를 수정한 후,
supabase functions deploy명령어를 다시 실행하면 새로운 버전으로 덮어쓰여 업데이트가 완료된다. 함수 삭제에 대한 명시적인 CLI 명령어는 공식 문서에서 뚜렷하게 제공되지 않으며, 일반적으로 Supabase 대시보드를 통해 삭제 작업을 수행한다.18
3.3 대시보드 기반 개발 워크플로우
Supabase는 CLI 중심의 전문적인 개발 워크플로우와 더불어, 초심자나 빠른 프로토타이핑을 선호하는 개발자를 위해 대시보드 내에서 모든 작업을 처리할 수 있는 통합 개발 환경을 제공한다.19 이는 두 가지 뚜렷한 개발자 페르소나, 즉 마찰 없는 경험을 원하는 ’프로토타이퍼/취미 개발자’와 GitOps 중심의 견고한 워크플로우를 선호하는 ’전문가/기업 팀’을 동시에 공략하려는 Supabase의 전략을 보여준다.
-
주요 기능:
-
온라인 코드 편집기: 브라우저 내에서 직접 코드를 작성하고 수정할 수 있다. 구문 강조(syntax highlighting) 및 Deno와 Supabase API에 대한 타입 체크 기능이 내장되어 있어 개발 편의성을 높인다.29
-
템플릿 제공: Stripe 웹훅 처리, OpenAI API 프록시, 스토리지 파일 업로드 등 자주 사용되는 일반적인 시나리오에 대한 사전 빌드된 코드 템플릿을 제공하여 개발 시작을 돕는다.19
-
내장 테스터: 별도의 도구 없이 대시보드 내에서 직접 HTTP 메서드, 헤더, 쿼리 파라미터, 요청 본문(payload)을 설정하여 함수를 테스트하고, 상태 코드와 응답 본문을 즉시 확인할 수 있다.19
-
AI 어시스턴트: 자연어 프롬프트를 입력하면 AI가 필요한 함수 코드를 자동으로 생성, 설명, 디버깅해주고 배포까지 수행하는 기능을 제공한다. 이는 Edge Functions에 대한 진입 장벽을 크게 낮춘다.19
-
한계 및 거버넌스 리스크:
이러한 대시보드 기반 워크플로우는 매우 편리하지만, 중요한 한계를 가진다. 대시보드 편집기는 Git과 같은 버전 관리 시스템과 연동되지 않으며, 변경 이력 추적이나 롤백 기능을 지원하지 않는다.19 따라서 공식 문서에서도 빠른 테스트나 프로토타이핑 용도로만 사용하고, 프로덕션에 배포될 코드는 반드시 Git 저장소에서 관리하며 CI/CD 파이프라인을 통해 배포할 것을 강력히 권장한다.
이 두 가지 개발 트랙(CLI vs. 대시보드)의 공존은 ’거버넌스 갭(governance gap)’이라는 잠재적 위험을 초래한다. 팀 환경에서 명확한 정책이 없다면, 긴급한 핫픽스를 대시보드를 통해 적용한 후 해당 변경 사항을 Git에 커밋하는 것을 잊어버릴 수 있다. 이러한 상황이 반복되면 버전 관리 시스템에 있는 코드(Source of Truth)와 실제 프로덕션에 배포된 코드 간에 차이가 발생하는 ’구성 드리프트(configuration drift)’가 발생하여, 운영상의 혼란과 예측 불가능한 버그를 야기할 수 있다. 따라서 Supabase를 도입하는 조직은 “프로토타입은 대시보드에서 자유롭게, 그러나 main 브랜치에 병합되는 모든 코드는 반드시 CLI와 CI/CD 파이프라인을 거쳐야 한다“는 명확한 내부 정책을 수립하고 준수해야 한다.
3.4 종속성 관리: import_map.json
Deno는 Node.js의 package.json과 node_modules 생태계와는 다른 방식으로 종속성을 관리한다. 중앙화된 패키지 레지스트리 대신, 웹 표준인 ES 모듈을 따라 URL을 통해 직접 모듈을 가져온다.22 예를 들어, import { serve } from "https://deno.land/std@0.140.0/http/server.ts";와 같이 코드를 작성한다. 이 방식은 별도의 npm install 과정이 없어 간결하지만, URL이 길어지고 여러 파일에서 동일한 모듈의 다른 버전을 참조하는 등 버전 관리가 복잡해질 수 있다.
이 문제를 해결하기 위해 Deno는 **import_map.json**이라는 표준화된 메커니즘을 제공한다.31
import_map.json 파일은 긴 모듈 URL에 짧고 의미 있는 별칭(alias)을 부여하는 역할을 한다.
- 사용법: Supabase 프로젝트에서는 관례적으로
supabase/functions/import_map.json경로에 이 파일을 위치시킨다. 이 파일 내부에imports키를 사용하여 모듈 별칭과 실제 URL을 매핑한다.22
{
"imports": {
"@supabase/supabase-js": "https://esm.sh/@supabase/supabase-js@2",
"stripe": "https://esm.sh/stripe@10.17.0?target=deno",
"shared/": "./_shared/"
}
}
위 예시에서는 @supabase/supabase-js라는 별칭을 해당 esm.sh URL에 매핑하고, shared/라는 접두사를 로컬의 _shared 디렉토리에 매핑했다.
- 적용:
import_map.json을 설정하고 나면, 함수 코드 내에서는 다음과 같이 간결하고 직관적인 방식으로 모듈을 가져올 수 있다.
import { createClient } from "@supabase/supabase-js";
import { corsHeaders } from "shared/cors.ts";
supabase functions serve 또는 supabase functions deploy 명령을 실행할 때, CLI는 supabase/functions/import_map.json 파일을 자동으로 감지하여 Deno 런타임에 적용해준다. 이를 통해 프로젝트 전체의 종속성 버전을 한 곳에서 중앙 관리할 수 있어 유지보수성이 크게 향상된다.22
3.5 로깅 및 디버깅 전략
안정적인 함수 개발과 운영을 위해서는 효과적인 로깅 및 디버깅 전략이 필수적이다. Supabase는 로컬과 프로덕션 환경 모두에서 체계적인 방법을 제공한다.
-
로깅:
-
로컬 환경: 로컬에서
supabase functions serve를 실행 중일 때, 함수 코드 내의console.log,console.warn,console.error출력은 해당 명령어를 실행한 터미널 창에 실시간으로 표시된다. 이를 통해 개발 과정에서 빠르고 직관적인 디버깅이 가능하다.33 -
프로덕션 환경: 배포된 함수에 대한 로그는 Supabase 대시보드에서 확인할 수 있다. 각 함수 상세 페이지에는 두 가지 주요 로그 뷰가 제공된다 33:
- Invocations: 각 함수 호출에 대한 상세 정보를 보여준다. 요청(Request) 헤더, 본문, 쿼리 파라미터와 응답(Response) 상태 코드, 본문, 실행 시간 등을 확인할 수 있어 특정 호출의 실패 원인을 분석하는 데 유용하다.
- Logs: 플랫폼 수준의 이벤트(배포, 부팅, 종료), 함수 내에서 발생한 처리되지 않은 예외(uncaught exceptions), 그리고
console문을 통해 출력된 모든 메시지를 시간순으로 보여준다.
-
이러한 로그 데이터는 내부적으로
logs.function_logs라는 Postgres 테이블에 저장되므로, 대시보드의 Log Explorer 기능을 사용하여 SQL 쿼리로 직접 로그를 조회하고 분석하는 것도 가능하다.5 -
Chrome DevTools를 이용한 로컬 디버깅:
단순한 console.log 디버깅을 넘어, 코드 실행을 단계별로 추적하고 변수 상태를 실시간으로 확인하는 등 보다 심층적인 디버깅을 위해 Supabase CLI는 Chrome DevTools와의 연동 기능을 제공한다. 이는 V8 엔진의 Inspector Protocol을 활용하는 방식이다.37
- 디버그 모드 실행: 터미널에서
supabase functions serve <function-name> --inspect-mode brk명령어를 실행한다.--inspect-mode brk플래그는 함수 서버를 디버그 모드로 시작하고, 첫 번째 코드 라인에서 실행을 즉시 중단(break)시킨다. - DevTools 연결: Chrome 브라우저를 열고 주소창에
chrome://inspect를 입력한다. ‘Devices’ 섹션에 원격 타겟이 나타나면, ‘Configure…’ 버튼을 클릭하여 네트워크 타겟으로127.0.0.1:8083을 추가한다. - 디버거 창 열기: 설정이 완료되면, “Open dedicated DevTools for Node” 링크가 나타난다. 이를 클릭하면 해당 함수에 연결된 별도의 DevTools 창이 열린다.
- 디버깅 시작:
curl이나 Postman 등으로 로컬 함수에 요청을 보내면, DevTools 창의 ‘Sources’ 탭에서 코드 실행이 첫 줄에 멈춰 있는 것을 확인할 수 있다. 이제 코드 라인 번호 옆을 클릭하여 중단점(breakpoint)을 설정하고, 실행을 재개(F8)하거나, 한 줄씩 실행(F10)하며 변수의 값을 조사하고 콜 스택을 분석하는 등 강력한 디버깅 기능을 활용할 수 있다.37
4. 핵심 기능 및 활용 사례
4.1 Supabase 생태계 연동
Supabase Edge Functions의 가장 강력한 특징은 Supabase 플랫폼의 다른 핵심 서비스들과의 매끄러운 통합이다. 함수는 고립된 실행 환경이 아니라, Supabase 백엔드를 프로그래밍 방식으로 제어하고 확장하는 관문 역할을 한다. 이러한 통합은 함수 내에서 자동으로 주입되는 사전 설정된 환경 변수들을 통해 이루어진다. SUPABASE_URL과 SUPABASE_ANON_KEY와 같은 변수들을 사용하여 별도의 설정 없이 즉시 Supabase 클라이언트 라이브러리(@supabase/supabase-js)를 초기화할 수 있다.2
- Supabase Auth 연동:
Edge Functions는 보안 모델의 핵심적인 부분을 담당한다. 클라이언트 애플리케이션에서 사용자가 로그인하면 발급되는 JWT(JSON Web Token)를 Edge Function으로 전달하여, 서버 측에서 사용자를 안전하게 식별하고 인증할 수 있다. 가장 일반적인 패턴은 클라이언트가 API 요청 시 Authorization 헤더에 Bearer
특히, supabase.auth.getUser(token) 메서드는 서버 측에서 JWT의 서명을 검증하고 유효성을 확인한 후 해당 사용자 정보를 반환해주는 안전하고 신뢰할 수 있는 방법이다. 클라이언트 측에서 세션 정보를 확인하는 getSession()과 달리, getUser()는 서버 간 통신에서 사용자 권한을 검증하는 데 반드시 사용되어야 한다.39
- Supabase Database 연동:
@supabase/supabase-js 클라이언트를 사용하면 함수 내에서 타입 세이프하게 Postgres 데이터베이스와 상호작용할 수 있다. 테이블에서 데이터를 조회(select), 생성(insert), 수정(update), 삭제(delete)하는 모든 작업이 가능하다. 또한, 데이터베이스에 미리 정의된 Postgres 함수를 원격 프로시저 호출(RPC) 방식으로 실행할 수도 있다.5
때로는 RLS 정책을 우회하여 시스템 관리자 수준의 작업을 수행해야 할 필요가 있다 (예: 사용자 데이터 일괄 처리, 민감한 로그 기록). 이러한 경우에는 SUPABASE_SERVICE_ROLE_KEY 환경 변수를 사용하여 관리자 권한을 가진 특수한 Supabase 클라이언트를 생성할 수 있다. 이 ‘서비스 롤’ 클라이언트는 모든 RLS 정책을 무시하므로, 매우 신중하게 사용해야 한다.22
- Supabase Storage 연동:
Edge Functions는 파일 처리와 관련된 복잡한 로직을 수행하는 데 이상적이다. 사용자가 파일을 업로드하기 전이나 후에 특정 작업을 수행할 수 있다. 예를 들어, 사용자가 대용량 ZIP 파일을 업로드하면, Edge Function이 이 요청을 받아 스트리밍 방식으로 파일의 압축을 풀고, 내부의 개별 파일들을 검증한 후 각각 Supabase Storage의 적절한 버킷에 저장하는 워크플로우를 구현할 수 있다.43 또한, 이미지 파일이 업로드되었을 때 썸네일을 자동으로 생성하거나, 워터마크를 삽입하는 등의 이미지 후처리 작업도 Edge Function을 통해 처리할 수 있다.4
4.2 주요 활용 패턴 및 시나리오
Supabase Edge Functions는 다양한 서버사이드 요구사항을 해결할 수 있는 유연한 도구다. 주요 활용 패턴은 다음과 같다.
- 웹훅 처리(Webhook Handling): Stripe에서 결제가 성공적으로 완료되었을 때, GitHub 리포지토리에 새로운 커밋이 푸시되었을 때, 혹은 Slack에 특정 메시지가 게시되었을 때와 같이 외부 서비스에서 발생하는 이벤트를 수신하는 엔드포인트 역할을 한다. 웹훅을 수신한 함수는 데이터베이스를 업데이트하거나, 사용자에게 알림을 보내는 등 후속 비즈니스 로직을 처리한다.3
- 서드파티 API 통합(Third-party API Integration): OpenAI의 GPT 모델을 호출하여 텍스트를 생성하거나, Twilio API를 통해 SMS 메시지를 발송하거나, Resend를 사용하여 이메일을 보내는 등 외부 API와의 연동을 안전하게 처리한다. API 키와 같은 민감한 자격증명 정보는 클라이언트 측에 노출하지 않고, Edge Function 내의 환경 변수로 안전하게 보관하여 호출한다.3
- 커스텀 API 엔드포인트(Custom API Endpoints): Supabase가 기본으로 제공하는 PostgREST API만으로는 구현하기 어려운 복잡한 비즈니스 로직이나 여러 테이블에 걸친 데이터 조작을 위한 맞춤형 API를 구축한다. RESTful 원칙에 따라 하나의 함수 내에서 요청의 HTTP 메서드(GET, POST, PUT, DELETE)를 분기하여 각기 다른 로직을 수행하는 ‘팻 함수(fat function)’ 패턴을 적용할 수 있다.3
- 백그라운드 작업 및 스케줄링(Background Jobs & Scheduling): 사용자의 요청과 즉시 동기적으로 처리될 필요가 없는 무거운 작업들을 수행한다. 예를 들어, 대용량 데이터 리포트 생성, 주기적인 데이터 동기화, 사용자 활동에 기반한 푸시 알림 일괄 전송 등이 있다. 외부 스케줄링 서비스(예: GitHub Actions cron, Trigger.dev)와 연동하여 특정 시간에 함수를 주기적으로 실행(cron job)하는 것도 가능하다.4
- 실시간 데이터 처리(Real-time Data Processing): Deno가 지원하는 WebSocket API를 활용하여 클라이언트와 실시간 양방향 통신 채널을 구축할 수 있다. 이를 통해 채팅 애플리케이션, 실시간 협업 도구, 라이브 대시보드와 같은 기능을 구현할 수 있다.43
4.3 실전 코드 예제: 인증된 사용자의 데이터 조회
다음은 Supabase Edge Functions의 가장 일반적이면서도 핵심적인 사용 사례를 보여주는 코드 예제다. 이 함수는 클라이언트로부터 JWT를 전달받아 사용자를 인증하고, 인증된 사용자의 ID를 기반으로 profiles 테이블에서 해당 사용자의 프로필 정보를 조회하여 반환한다.
// supabase/functions/get-user-profile/index.ts
import { createClient } from 'npm:@supabase/supabase-js@2'
import { corsHeaders } from '../_shared/cors.ts' // CORS 헤더를 공통 모듈에서 가져옴
// Deno의 내장 HTTP 서버를 사용하여 요청을 처리
Deno.serve(async (req) => {
// 웹 브라우저가 보내는 CORS 사전 확인(preflight) 요청(OPTIONS 메서드)을 처리.
// 실제 로직을 실행하지 않고 즉시 'ok' 응답을 보내야 한다.
if (req.method === 'OPTIONS') {
return new Response('ok', { headers: corsHeaders })
}
try {
// 1. 요청 헤더에서 'Authorization' 값을 가져온다.
const authHeader = req.headers.get('Authorization')
if (!authHeader) {
throw new Error('Authorization header is missing')
}
// 'Bearer ' 접두사를 제거하여 순수한 JWT만 추출한다.
const token = authHeader.replace('Bearer ', '')
// 2. 사용자 인증을 위한 Supabase 클라이언트를 생성한다.
// 중요한 점은 `global.headers` 옵션을 통해 원본 요청의 Authorization 헤더를
// 그대로 전달하는 것이다. 이렇게 함으로써 이 클라이언트로 수행하는 모든 작업은
// 해당 사용자의 권한으로 실행되며, RLS 정책이 적용된다.
const supabaseClient = createClient(
Deno.env.get('SUPABASE_URL')?? '',
Deno.env.get('SUPABASE_ANON_KEY')?? '',
{
global: {
headers: { Authorization: `Bearer ${token}` }
}
}
)
// 3. 서버 측에서 JWT를 안전하게 검증하고 사용자 정보를 가져온다.
// 이 과정에서 토큰이 유효하지 않거나 만료되었다면 에러가 발생한다.
const { data: { user }, error: userError } = await supabaseClient.auth.getUser()
if (userError) throw userError
// 4. 인증된 사용자의 고유 ID(`user.id`)를 사용하여 'profiles' 테이블에서
// 해당 사용자의 프로필 데이터를 조회한다. `.single()`은 결과가 정확히
// 한 행일 것으로 예상하며, 그렇지 않으면 에러를 발생시킨다.
const { data: profile, error: profileError } = await supabaseClient
.from('profiles')
.select('*')
.eq('id', user.id)
.single()
if (profileError) throw profileError
// 성공적으로 프로필을 조회한 경우, JSON 형태로 응답한다.
return new Response(JSON.stringify({ profile }), {
headers: {...corsHeaders, 'Content-Type': 'application/json' },
status: 200,
})
} catch (error) {
// 과정 중 어떤 단계에서든 에러가 발생하면, 400번대 상태 코드와 함께
// 에러 메시지를 JSON 형태로 응답한다.
return new Response(JSON.stringify({ error: error.message }), {
headers: {...corsHeaders, 'Content-Type': 'application/json' },
status: 400,
})
}
})
코드 분석: 이 예제는 Edge Function이 어떻게 클라이언트 측 로직을 보완하는 안전한 서버사이드 게이트웨이 역할을 하는지를 명확하게 보여준다.24 클라이언트는 자신의 JWT를 전달하는 것 외에 다른 민감한 정보를 노출할 필요가 없다. 모든 데이터베이스 접근과 사용자 인증 검증은 서버 측의 안전한 환경에서 이루어진다. 이 패턴을 통해 클라이언트 측 코드의 복잡성을 줄이고, RLS와 같은 Supabase의 강력한 보안 기능을 최대한 활용하면서 비즈니스 로직을 안전하게 확장할 수 있다.
5. 제약 사항, 성능, 그리고 보안
5.1 플랫폼 및 런타임 제약 사항
Supabase Edge Functions는 강력하고 유연한 도구이지만, 무한한 리소스를 제공하는 것은 아니다. 안정적인 서비스 운영과 플랫폼 남용 방지를 위해 Supabase는 각 플랜별로 명시적인 기술적, 정책적 제약 사항을 두고 있다.45 애플리케이션을 설계하고 개발하는 단계에서 이러한 한계를 명확히 인지하고 그에 맞춰 아키텍처를 구성하는 것이 매우 중요하다.
주요 제약 사항은 다음과 같다 46:
- 최대 메모리: 각 함수 인스턴스에 할당되는 최대 메모리는 256MB로 제한된다. 대용량 데이터를 메모리에 로드하여 처리하는 작업에는 적합하지 않을 수 있다.
- 최대 실행 시간 (Wall clock limit): 함수 워커가 활성 상태로 유지될 수 있는 총 시간이다. 이 시간 동안 여러 요청을 처리하거나 백그라운드 작업을 수행할 수 있다.
- Free Plan: 150초
- 유료 플랜 (Pro, Team 등): 400초
- 최대 CPU 시간: 하나의 요청을 처리하는 동안 순수하게 CPU를 사용한 시간의 한계는 2초다. 네트워크 I/O와 같이 CPU를 사용하지 않고 대기하는 비동기 작업 시간은 이 계산에 포함되지 않는다. CPU 집약적인 계산이 2초 이상 소요되면 함수가 강제 종료될 수 있다.
- 요청 유휴 타임아웃 (Request idle timeout): 함수가 요청을 받은 후 응답을 보내지 않고 유휴 상태로 대기할 수 있는 최대 시간은 150초다. 이 시간을 초과하면 클라이언트에게
504 Gateway Timeout오류가 반환된다. - 최대 함수 크기: Supabase CLI를 사용하여 번들링(bundling)한 후의 최종 함수 코드 크기는 20MB를 초과할 수 없다.
- 프로젝트당 최대 함수 개수:
- Free Plan: 100개
- Pro Plan: 500개
- Team Plan: 1000개
- Enterprise Plan: 무제한
- 기타 기술적 제약: 보안상의 이유로 이메일 발송에 사용되는 표준 포트인 25번과 587번으로의 아웃바운드 네트워크 연결이 차단된다. 이메일을 보내려면 Resend와 같은 서드파티 이메일 API 서비스를 사용해야 한다. 또한, 브라우저 환경에서 제공되는 Web Worker API나 Node.js의
vm모듈과 같은 동적 코드 실행 기능은 사용할 수 없다.46
5.2 성능 특성 및 고려사항
V8 Isolate 기반 아키텍처 덕분에 Supabase Edge Functions는 이론적으로 매우 빠른 콜드 스타트 성능을 가진다. 그러나 실제 사용 환경에서는 런타임 자체의 성능 외에 네트워크 오버헤드와 플랫폼 인프라의 특성이 전체적인 체감 성능에 더 큰 영향을 미친다.
가장 중요한 고려사항은 ’Edge’라는 마케팅 용어가 주는 기대치와 실제 관측되는 성능 간의 괴리다. 다수의 커뮤니티 사용자 보고에 따르면, Supabase Edge Functions는 특히 높은 동시성 요청 처리와 일관된 저지연 시간 보장 측면에서 어려움을 겪는 것으로 보인다. 간단한 ‘hello world’ 수준의 함수조차도 응답 시간이 수백 ms에서 1초 이상으로 불안정하게 측정되거나, 분당 수십 회 이상의 동시 요청 시 일부 요청이 실패하는 현상이 보고되었다.47
이러한 성능 병목의 근본 원인은 Deno 런타임이나 V8 Isolate 자체의 문제라기보다는, 사용자 요청이 실제 함수 코드에 도달하기까지 거치는 Supabase의 자체 인프라 스택(API 게이트웨이, 리버스 프록시, 요청 릴레이 등)에서 발생하는 오버헤드일 가능성이 높다. 한 사용자는 함수 자체의 부팅 시간은 20ms에 불과했지만, 전체 요청-응답 시간은 훨씬 길었다고 보고하며 이를 “네트워크 스택“의 문제로 지적했다.47 또 다른 사용자는 Supabase 게이트웨이에서만 1초 이상의 오버헤드가 발생한다고 측정했으며, Supabase가 내부적으로 사용하는 Deno Deploy에 직접 배포했을 때보다 Supabase Edge Functions의 성능이 현저히 느리다는 비교 결과를 공유하기도 했다.47
이러한 증거들은 현재 Supabase Edge Functions의 성능이 플랫폼의 게이트웨이 인프라에 의해 제한되고 있음을 강력하게 시사한다. 이는 ’엣지’가 제공하는 낮은 지연 시간이라는 핵심 가치를 상당 부분 희석시키는 요인이다. 따라서 수십 밀리초 단위의 매우 낮은 지연 시간이 비즈니스에 치명적으로 중요한 실시간 애플리케이션이나 고성능 API를 구축하려는 경우, Supabase Edge Functions는 잠재적으로 높은 리스크를 가진 선택일 수 있다. 도입 전 실제 워크로드와 유사한 환경에서 철저한 성능 벤치마크(PoC)를 수행하는 것이 필수적이다.
5.3 보안 모범 사례
Edge Functions는 서버사이드 코드를 실행하므로, 보안은 최우선 고려사항이 되어야 한다. 안전한 함수를 구축하기 위한 핵심적인 모범 사례는 다음과 같다.
- API 키 및 시크릿 관리:
SUPABASE_SERVICE_ROLE_KEY와 같이 데이터베이스에 대한 전체 접근 권한을 가진 민감한 키는 절대로 코드에 하드코딩하거나 클라이언트 측에 노출해서는 안 된다. 모든 시크릿 정보는 Supabase 대시보드의 ‘Settings’ > ‘Secrets’ 메뉴 또는supabase secrets setCLI 명령을 통해 환경 변수로 안전하게 주입해야 한다. 이렇게 설정된 시크릿은 암호화되어 저장되며, 함수 실행 시에만 안전하게 접근할 수 있다.50 - 엄격한 입력값 검증: 외부로부터 함수로 전달되는 모든 데이터(요청 본문, 쿼리 파라미터, 헤더 등)는 신뢰할 수 없는 것으로 간주해야 한다. 함수 로직의 시작 부분에서 항상 입력값의 타입, 형식, 범위를 철저히 검증하여 SQL 인젝션, 크로스 사이트 스크립팅(XSS), 데이터 오염과 같은 공격을 방지해야 한다. Zod와 같은 라이브러리를 사용하면 스키마 기반의 강력한 검증을 쉽게 구현할 수 있다.50
- JWT 검증의 생활화: Edge Functions는 기본적으로
Authorization헤더에 유효한 Supabase JWT가 포함되어 있는지 검증한다. 이 기능은 사용자가 인증되었는지 확인하는 1차 방어선이다. Stripe 웹훅과 같이 외부 시스템에서 호출되어 JWT가 없는 예외적인 경우를 제외하고는,--no-verify-jwt플래그를 사용하여 이 검증을 비활성화하는 것을 피해야 한다. 함수 내에서도supabase.auth.getUser()를 호출하여 토큰의 유효성을 다시 한번 확인하는 것이 안전하다.25 - RLS와의 연계 설계: 데이터 접근 제어의 중심은 RLS(Row-Level Security)에 두어야 한다. Edge Function은 가능한 한 최소한의 권한을 가진 일반 사용자의 JWT를 전달받아, 해당 사용자의 컨텍스트에서 RLS 정책을 준수하며 데이터베이스와 상호작용하도록 설계하는 것이 가장 안전한 아키텍처다. 시스템 전체에 영향을 미치는 관리자급 권한이 반드시 필요한 극히 제한적인 경우에만
service_role_key를 사용해야 한다. 이는 권한 상승 공격의 위험을 최소화한다.50
6. 비용 모델 분석
6.1 가격 책정 구조
Supabase Edge Functions의 비용 모델은 개발자가 이해하고 예측하기 쉽도록 매우 단순하게 설계되었다. 복잡한 변수들을 제거하고, 핵심적인 사용량 지표인 함수 호출(invocation) 횟수를 기준으로 과금한다.52
- 핵심 과금 단위: 기본 가격은 100만 호출당 $2이다. 이 가격에는 함수 실행에 필요한 CPU 시간, 메모리 사용량(GB-second) 등 모든 컴퓨팅 비용이 포함되어 있다. 이는 요청 수와 컴퓨팅 시간을 별도로 계산하여 합산하는 AWS Lambda의 복잡한 비용 모델과 비교했을 때 큰 장점이다. 함수가 얼마나 오래, 얼마나 많은 리소스를 사용했는지에 관계없이 오직 호출된 횟수만으로 비용이 결정되므로, 비용 예측이 매우 용이하다.52
- 플랜별 무료 할당량: Supabase는 각 요금제 플랜에 따라 매월 일정량의 무료 함수 호출을 제공한다. 이 할당량을 초과하는 사용량에 대해서만 추가 비용이 발생한다.52
- Free Plan: 월 500,000 호출
- Pro Plan: 월 2,000,000 호출
- Team Plan: 월 2,000,000 호출
- 과금 방식: 과금은 패키지 단위로 이루어진다. 예를 들어, Pro 플랜 사용자가 한 달에 340만 번의 함수를 호출했다면, 무료 할당량 200만 회를 제외한 140만 회의 초과 사용량이 발생한다. 이 경우, 100만 호출 패키지 2개에 해당하는 $4가 청구된다. 즉, 100만 1회를 호출하더라도 200만 회에 해당하는 비용이 청구되는 방식이다.53
6.2 비용 최적화 전략
단순한 가격 모델 덕분에 비용 최적화 전략 또한 비교적 명확하다. 핵심은 불필요한 함수 호출 횟수를 줄이는 것이다.
- “팻 함수(Fat Functions)” 설계: Supabase는 여러 개의 작고 세분화된 함수(마이크로서비스와 유사한 접근)보다는, 관련된 로직을 하나의 함수에 모아 처리하는 “팻 함수” 설계를 권장한다.26 예를 들어, 사용자 프로필과 관련된 생성(POST), 조회(GET), 수정(PUT) 로직을 각각 별도의 함수로 만드는 대신,
user-profile이라는 단일 함수 내에서 HTTP 메서드에 따라 로직을 분기하는 방식이다. 이는 클라이언트가 여러 번의 API 호출을 해야 할 작업을 한 번의 호출로 줄여주어 총 호출 횟수를 감소시키고, 함수 관리의 복잡성을 낮추는 효과가 있다.
-
사용량 모니터링: Supabase 대시보드의 ‘Usage’ 섹션에서 실시간으로 함수 호출 횟수를 모니터링할 수 있다. 정기적으로 사용량 추이를 확인하여 특정 함수의 호출이 비정상적으로 급증하는 경우를 조기에 발견하고 원인을 분석해야 한다. 예를 들어, 클라이언트 측의 버그로 인해 동일한 함수가 반복적으로 호출되는 경우, 이를 방치하면 예기치 않은 큰 비용이 발생할 수 있다.55
-
효율적인 로직과 캐싱: 함수 내부 로직의 효율성도 간접적으로 비용에 영향을 미칠 수 있다. 예를 들어, 자주 변경되지 않는 데이터를 외부 API에서 가져오는 함수의 경우, 결과를 Supabase 데이터베이스나 외부 캐시(예: Upstash Redis)에 저장하여 후속 호출 시에는 캐시된 데이터를 반환하도록 구현하면 불필요한 API 호출과 함수 실행을 줄일 수 있다. 또한, 데이터베이스 쿼리를 최적화하여 함수 실행 시간을 단축하면 전체 시스템의 부하를 줄여 안정성을 높일 수 있다.
7. 경쟁 서비스와의 비교 분석
7.1 Supabase Edge Functions vs. AWS Lambda
Supabase Edge Functions와 AWS Lambda는 서버리스 컴퓨팅 시장에서 직접적인 경쟁 관계에 있지만, 그들의 철학과 목표 시장은 뚜렷하게 구분된다. Supabase는 **‘개발자 경험과 Supabase 생태계로의 통합’**에 초점을 맞추는 반면, AWS Lambda는 **‘최고의 유연성, 다양한 런타임 지원, 그리고 거대한 AWS 생태계와의 연동’**에 중점을 둔다.54
| 항목 | Supabase Edge Functions | AWS Lambda |
|---|---|---|
| 실행 단위 | V8 Isolate (경량, 수 ms 내 시작) | Firecracker MicroVM (경량 VM, 수백 ms 내 시작) |
| 지원 런타임 | Deno (TypeScript/JavaScript 전용) | Node.js, Python, Go, Java, Ruby,.NET 등 다수 |
| 콜드 스타트 | 이론적으로 매우 짧으나, 게이트웨이 오버헤드 존재 | 상대적으로 길며, 프로비저닝된 동시성으로 완화 가능 |
| 생태계 통합 | Supabase(DB, Auth, Storage)에 매우 긴밀하게 통합 | AWS(S3, DynamoDB, SQS, API Gateway 등) 생태계 전반에 통합 |
| 개발 복잡도 | 낮음 (단순한 CLI 및 배포, 추상화된 인프라) | 높음 (IAM 역할, VPC, 보안 그룹 등 복잡한 설정 필요) |
| 이식성 | 높음 (오픈소스 Deno 기반으로 벤더 종속성 낮음) | 낮음 (AWS 서비스에 대한 의존성이 높아 벤더 종속성 강함) |
비용 모델 측면에서도 두 서비스는 다른 접근 방식을 취한다. Supabase는 호출 횟수에 따라 컴퓨팅 비용이 포함된 고정 요금(2/1M)을 부과하여 예측 가능성을 높였다. 반면, Lambda는 호출 수(0.2/1M)와 컴퓨팅 시간(GB-초)을 별도로 과금한다. 이는 실행 시간이 짧고 메모리 사용량이 적은 함수는 Lambda가 더 저렴할 수 있지만, 실행 시간이 길거나 리소스 사용량이 많은 함수는 비용이 급격히 증가할 수 있음을 의미한다.54
적합한 사용 사례를 결정할 때, 프로젝트의 맥락이 가장 중요하다. 이미 Supabase 생태계를 기반으로 애플리케이션을 구축하고 있으며, 데이터베이스 트리거나 외부 서비스 연동과 같은 백엔드 로직을 빠르게 확장하고자 한다면 Edge Functions가 압도적으로 유리하다. 개발 속도와 편의성이 핵심적인 장점이다. 그러나 프로젝트가 Python 기반의 데이터 분석 라이브러리를 사용해야 하거나, AWS SQS, Kinesis와 같은 특정 AWS 서비스와 복잡한 비동기 워크플로우를 구성해야 한다면, AWS Lambda의 유연성과 광범위한 생태계 지원이 더 적합한 선택이 될 것이다.57
7.2 Supabase Edge Functions vs. Cloudflare Workers
Supabase Edge Functions와 Cloudflare Workers는 둘 다 V8 Isolate를 기반으로 하는 고성능 엣지 컴퓨팅 서비스라는 점에서 기술적으로 매우 유사하다. 하지만 그들의 전략적 포지셔닝은 다르다. Cloudflare의 핵심 역량은 글로벌 CDN과 네트워크 성능 최적화에 있으며, Workers는 이러한 네트워크의 프로그래밍 가능성을 극대화하는 도구다. 반면, Supabase의 강점은 통합된 백엔드 플랫폼에 있으며, Edge Functions는 이 플랫폼을 확장하는 역할을 한다.
성능 측면에서는 실제 사용자들의 벤치마크 결과, 순수한 네트워크 지연 시간과 응답 속도 면에서는 Cloudflare Workers가 Supabase Edge Functions보다 일관되게 우수한 성능을 보이는 경향이 있다.48 이는 Cloudflare가 세계에서 가장 광범위한 엣지 로케이션을 보유하고 있으며, 네트워크 라우팅 최적화에 대한 깊은 전문성을 가지고 있기 때문이다.
개발 경험 측면에서는 각자의 강점이 뚜렷하다. Supabase는 Auth, Database와의 연동이 내장되어 있고, supabase-js SDK를 통해 매끄러운 백엔드 개발 경험을 제공한다.59 반면, Cloudflare는 Workers를 중심으로 KV(키-값 스토어), R2(객체 스토리지), D1(SQL 데이터베이스) 등 자체적인 분산 스토리지 생태계를 구축하고 있지만, Supabase처럼 하나의 SDK와 관리 UI로 통합된 경험을 제공하지는 않는다.59
비용 모델은 두 서비스 모두 사용량 기반이지만, Cloudflare Workers는 요청 수와 CPU 시간을 기준으로 더 세분화된 과금 체계를 가지고 있어, 사용 패턴에 따라 비용이 더 유연하게 변동될 수 있다.61
결론적으로, API의 응답 속도가 비즈니스의 성패를 좌우하는 애플리케이션(예: 광고 입찰, 실시간 게임 API)이라면 Cloudflare Workers가 더 나은 선택이다. 그러나 이미 Supabase를 사용 중인 프로젝트에서 데이터베이스와 연동되는 서버리스 로직을 추가하는 것이 주된 목적이라면, 개발 생산성과 통합의 용이성 측면에서 Supabase Edge Functions가 훨씬 효율적이다.60
7.3 Supabase Edge Functions vs. Database Functions
Supabase는 두 가지 종류의 함수를 제공하며, 이 둘을 혼동하지 않는 것이 중요하다. Edge Function과 Database Function은 실행되는 위치와 주된 목적에서 근본적인 차이를 가진다.44
| 기준 | Supabase Edge Functions | Supabase Database Functions (Postgres) |
|---|---|---|
| 언어 | TypeScript (Deno 런타임 사용) | SQL, PL/pgSQL 등 Postgres 지원 언어 |
| 실행 위치 | 글로벌 엣지 네트워크 (데이터베이스 외부의 별도 서버) | PostgreSQL 데이터베이스 엔진 내부 |
| 주요 용도 | HTTP API 엔드포인트 제공, 외부 API 호출, 웹훅 처리, 파일 처리 | 데이터 유효성 검사, DB 트리거 로직, 복잡한 쿼리 캡슐화, 데이터 변환 |
| 성능 특성 | 네트워크 지연 시간 발생 (데이터베이스와 통신 시) | 데이터와 동일한 위치에서 실행되어 네트워크 오버헤드 없이 매우 빠름 |
| 외부 통신 | 가능 (HTTP 요청, 이메일 발송 등 외부 네트워크 접근 가능) | 불가능 (데이터베이스 외부의 네트워크와 통신할 수 없음) |
| 상태 관리 | 무상태(Stateless)로 설계하는 것을 권장 | 상태 저장(Stateful) 가능, 데이터베이스 트랜잭션 보장 |
선택 가이드는 명확하다. 수행하려는 작업이 순수하게 데이터베이스 내의 데이터 조작으로 완결될 수 있다면 Database Function을 사용하는 것이 가장 효율적이다. 예를 들어, users 테이블에 새로운 행이 삽입될 때마다 트리거를 통해 profiles 테이블에 해당 사용자의 프로필 행을 자동으로 생성하는 로직은 Database Function으로 구현하는 것이 최적이다. 데이터와 로직이 같은 공간에 있어 불필요한 네트워크 통신 없이 즉각적으로 처리되기 때문이다.
반면, 로직 수행 과정에서 데이터베이스 외부 세계와의 상호작용이 단 하나라도 필요하다면 반드시 Edge Function을 사용해야 한다. 예를 들어, 사용자 가입 시 Stripe API를 호출하여 결제 고객을 생성하거나, Resend API를 통해 환영 이메일을 보내거나, 사용자가 업로드한 주소 문자열을 Google Maps API로 보내 위경도 좌표를 받아오는 작업 등은 Database Function으로는 절대 수행할 수 없다. 이처럼 외부 서비스 연동, HTTP 기반의 API 제공, 서버사이드 렌더링 지원 등 현대적인 웹 애플리케이션의 백엔드 로직 대부분은 Edge Function의 영역에 속한다.44
8. 종합 평가 및 전략적 권장 사항
8.1 Supabase Edge Functions의 강점과 약점
본 안내서의 심층 분석을 통해 도출된 Supabase Edge Functions의 핵심적인 강점과 약점은 다음과 같다.
강점:
- 탁월한 개발자 경험 (DX): Supabase 데이터베이스, 인증, 스토리지와의 완벽한 통합은 다른 어떤 서버리스 플랫폼도 제공하지 못하는 독보적인 장점이다. 복잡한 설정 없이 즉시 백엔드 로직을 확장할 수 있어 개발 생산성을 극적으로 향상시킨다.
- Deno 기반의 현대적 아키텍처: TypeScript를 네이티브로 지원하고, 기본적으로 안전한 샌드박스 환경을 제공하는 Deno 런타임을 채택하여 코드의 안정성과 보안성을 높였다.
- 예측 가능한 비용 모델: 호출 횟수 기반의 단순하고 투명한 과금 체계는 복잡한 컴퓨팅 비용 계산 없이 예산을 계획하고 관리하기 용이하게 만든다.
- 벤더 종속성 탈피: Deno, Postgres와 같은 검증된 오픈소스 기술을 기반으로 하므로, 필요 시 자체 호스팅 환경으로 이전할 수 있는 유연성을 제공하여 특정 클라우드 제공업체에 대한 종속성을 최소화한다.
약점:
- 성능의 불확실성: ’Edge’라는 이름이 주는 저지연성에 대한 기대와 달리, 실제 사용자 환경에서는 Supabase의 게이트웨이 오버헤드로 인해 상대적으로 높은 지연 시간과 동시성 처리 한계가 보고되고 있다. 이는 성능에 민감한 애플리케이션에 도입할 때 가장 큰 위험 요소다.
- 제한된 런타임 지원: Deno 런타임, 즉 TypeScript와 JavaScript만 지원하므로, Python, Go, Java 등 다른 프로그래밍 언어로 작성된 기존의 서버리스 자산을 보유하고 있거나, 특정 언어의 라이브러리 생태계가 필수적인 팀에게는 진입 장벽으로 작용한다.
- 상대적 미성숙: AWS Lambda나 Cloudflare Workers와 같은 시장의 선두 주자들과 비교했을 때, 기능의 깊이, 써드파티 도구 생태계, 대규모 운영 안정성 측면에서 아직 발전하고 있는 단계다. 일부 고급 기능이나 세밀한 제어 옵션이 부족할 수 있다.
8.2 도입을 위한 프로젝트 유형 제안
이러한 강점과 약점을 종합적으로 고려했을 때, Supabase Edge Functions의 도입을 추천하거나 신중한 접근이 필요한 프로젝트 유형은 다음과 같이 분류할 수 있다.
적극적으로 도입을 추천하는 프로젝트:
- Supabase를 주력 백엔드로 사용하는 프로젝트의 기능 확장: 이미 Supabase의 데이터베이스와 인증 시스템을 사용하고 있는 경우, Edge Functions는 가장 자연스럽고 효율적인 서버사이드 로직 확장 수단이다.
- 빠른 프로토타이핑 및 MVP(Minimum Viable Product) 개발: 인프라 설정에 드는 시간을 최소화하고 아이디어를 빠르게 검증해야 하는 스타트업이나 신규 프로젝트에 매우 적합하다.
- 내부 관리자 도구나 복잡하지 않은 API 백엔드 구축: 극도의 저지연성이나 대규모 동시성이 요구되지 않는 내부용 애플리케이션이나 중소 규모의 공개 API를 구축하는 데 비용 효율적이고 생산적인 선택이다.
- 서드파티 서비스 연동이 핵심인 애플리케이션: 웹훅 처리, 외부 API 호출 등 다른 서비스들을 연결하는 ‘글루 코드(glue code)’ 역할에 특화되어 있다.
도입 전 신중한 검토가 필요한 프로젝트:
- 저지연성이 핵심 요구사항인 실시간 서비스: 온라인 게임의 매치메이킹 서버, 금융 거래 시스템, 실시간 입찰 시스템과 같이 수십 밀리초 단위의 응답 시간이 비즈니스에 직접적인 영향을 미치는 경우, 현재 보고되는 성능으로는 요구사항을 충족하지 못할 가능성이 있다.
- 대규모 동시 접속 처리가 필요한 고성능 API: 소셜 미디어의 피드 API나 대규모 이벤트의 티켓팅 시스템과 같이 예측 불가능한 트래픽 스파이크와 높은 동시 요청을 안정적으로 처리해야 하는 경우, 현재의 동시성 처리 능력에 대한 추가적인 검증이 필요하다.
- 기존 서버리스 자산의 마이그레이션: 이미 Python이나 Go 등으로 복잡한 서버리스 로직을 구축하여 운영 중인 경우, 이를 모두 TypeScript로 재작성하는 비용과 Deno 생태계의 라이브러리 지원 여부를 신중하게 평가해야 한다.
8.3 성공적 도입을 위한 최종 권고
Supabase Edge Functions를 성공적으로 도입하고 활용하기 위한 최종적인 전략적 권고는 다음과 같다.
- 정확한 역할 이해: Supabase Edge Functions를 모든 문제를 해결하는 ’만능 서버리스 해결사’로 접근해서는 안 된다. 그보다는 **‘Supabase BaaS를 위한 강력하고 통합된 확장 도구’**로 명확히 이해하고, 그 강점이 가장 잘 발휘될 수 있는 영역에 집중해야 한다.
- 철저한 성능 검증 (PoC): 실제 도입을 결정하기 전에, 애플리케이션의 핵심적인 사용 사례와 유사한 부하 테스트를 포함하는 PoC(Proof of Concept)를 반드시 수행해야 한다. 이 과정을 통해 실제 환경에서의 지연 시간, 콜드 스타트, 동시성 처리 능력을 객관적으로 측정하고, 이것이 프로젝트의 성능 요구사항을 만족하는지 검증해야 한다.
- 보안 거버넌스 수립: Deno의 권한 모델은 강력하지만, 개발자의 올바른 사용에 의존한다. 팀 내에서 ’최소 권한의 원칙’을 적용하는 코드 리뷰 가이드라인을 수립하고,
--allow-all과 같은 광범위한 권한 부여를 금지해야 한다. 또한, 모든 시크릿은 CLI와 환경 변수를 통해 관리하는 것을 원칙으로 삼아야 한다. - GitOps 기반 배포 전략 채택: 프로덕션 환경의 안정성과 예측 가능성을 확보하기 위해, 대시보드를 통한 코드의 직접적인 수정 및 배포를 엄격히 금지해야 한다. 모든 함수 코드는 Git 저장소에서 버전 관리되어야 하며, Supabase CLI와 GitHub Actions와 같은 CI/CD 파이프라인을 연동하여 테스트와 배포가 자동화된 GitOps 기반의 워크플로우를 구축하는 것이 필수적이다. 이는 코드 변경에 대한 추적 가능성을 보장하고, 인적 실수를 최소화하며, 안정적인 운영의 기반이 된다.
9. 참고 자료
- develop-const.tistory.com, https://develop-const.tistory.com/34#:~:text=Supabase%20Edge%20Functions%EC%9D%80%20Supabase,%EB%A5%BC%20%EC%A0%9C%EA%B3%B5%ED%95%A0%20%EC%88%98%20%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4.
- Supabase Edge Functions Quickstart - YouTube, https://www.youtube.com/watch?v=5OWH9c4u68M&pp=0gcJCdgAo7VqN5tD
- Deno Edge Functions | Supabase Features, https://supabase.com/features/deno-edge-functions
- Edge Functions | Supabase Docs, https://supabase.com/docs/guides/functions
- Supabase Edge Functions - Deploy JavaScript globally in seconds, https://supabase.com/edge-functions
- Supabase edge functions를 사용해보자 - 호두의 개발스토리 - 티스토리, https://develop-const.tistory.com/34
- Security and permissions - Deno Docs, https://docs.deno.com/runtime/fundamentals/security/
- Exploring Deno 2: Features, Benefits, and Getting Started - DEV Community, https://dev.to/runtime_terrors/exploring-deno-2-features-benefits-and-getting-started-2n3d
- Welcome to Jurassic Park: A Comprehensive Study of Security Risks in Deno and its Ecosystem, https://www.ndss-symposium.org/wp-content/uploads/2025-284-paper.pdf
- Supabase Edge Functions - Hacker News, https://news.ycombinator.com/item?id=30868849
- 2.9 V8 - The Internals of Deno - GitBook, https://choubey.gitbook.io/internals-of-deno/architecture/v8
- The Anatomy of an Isolate Cloud | Deno, https://deno.com/blog/anatomy-isolate-cloud
- v8: Isolate Class Reference - v8docs, https://v8docs.nodesource.com/node-0.8/d5/dda/classv8_1_1_isolate.html
- V8 Isolates are taking over the world - DEV Community, https://dev.to/tomlienard/v8-isolates-are-taking-over-the-world-3h4m
- supabase/edge-runtime: A server based on Deno runtime, capable of running JavaScript, TypeScript, and WASM services. - GitHub, https://github.com/supabase/edge-runtime
- Supabase Functions on Deno Deploy, https://deno.com/blog/supabase-functions-on-deno-deploy
- Welcome to Jurassic Park: A Comprehensive Study of Security Risks in Deno and its Ecosystem, https://cispa.de/en/research/publications/84103-welcome-to-jurassic-park-a-comprehensive-study-of-security-risks-in-deno-and-its-ecosystem
- Getting Started with Edge Functions | Supabase Docs, https://supabase.com/docs/guides/functions/quickstart
- Edge Functions: Deploy from the Dashboard + Deno 2.1 - Supabase, https://supabase.com/blog/supabase-edge-functions-deploy-dashboard-deno-2-1
- Deno Edge Functions Setup - YouTube, https://www.youtube.com/watch?v=uZ6R9p3mgWM
- How to import my supabase db types in edge functions (Deno)? - Stack Overflow, https://stackoverflow.com/questions/78979217/how-to-import-my-supabase-db-types-in-edge-functions-deno
- Working with Supabase Edge Functions for Basejump - Basejump, https://usebasejump.com/blog/working-with-supabase-edge-functions
- Supabase Edge Functions - Hono, https://hono.dev/docs/getting-started/supabase-functions
- Using Edge Functions in Supabase: A complete guide - LogRocket Blog, https://blog.logrocket.com/using-edge-functions-supabase-complete-guide/
- Deploy to Production | Supabase Docs, https://supabase.com/docs/guides/functions/deploy
- Development tips | Supabase Docs, https://supabase.com/docs/guides/functions/development-tips
- Python: Delete data | Supabase Docs, https://supabase.com/docs/reference/python/delete
- User Deletion in an Edge Function - Supabase - Reddit, https://www.reddit.com/r/Supabase/comments/1kvyqcm/user_deletion_in_an_edge_function/
- Getting Started with Edge Functions (Dashboard) | Supabase Docs, https://supabase.com/docs/guides/functions/quickstart-dashboard
- Supabase Edge Functions Just Got Way Easier - YouTube, https://www.youtube.com/watch?v=Tkk1UXXR3xw
- JavaScript Import Maps in Edge Functions - YouTube, https://www.youtube.com/watch?v=ILr3cneZuFk
- Struggling with Edge Functions - Supabase - Reddit, https://www.reddit.com/r/Supabase/comments/1jaey5r/struggling_with_edge_functions/
- Debugging Edge Functions | Supabase Docs - Vercel, https://docs-n3gxhwtbf-supabase.vercel.app/docs/guides/functions/debugging
- Logging | Supabase Docs, https://supabase.com/docs/guides/functions/logging
- Debugging Supabase Edge Functions | Buildcamp Guides, https://www.buildcamp.io/guides/debugging-supabase-edge-functions
- Logging | Supabase Docs, https://supabase.com/docs/guides/telemetry/logs
- Local Debugging | Supabase Docs, https://supabase.com/docs/guides/functions/debugging-tools
- Integrating with Supabase Database (Postgres), https://supabase.com/docs/guides/functions/connect-to-postgres
- Supabase Edge Functions: a working template with a catch - WeWeb Community, https://community.weweb.io/t/supabase-edge-functions-a-working-template-with-a-catch/9530
- How can I authorize user in edge function? · supabase · Discussion #21907 - GitHub, https://github.com/orgs/supabase/discussions/21907
- JavaScript: Retrieve a user | Supabase Docs, https://supabase.com/docs/reference/javascript/auth-getuser
- Executing Dynamic JavaScript Code on Supabase with Edge Functions, https://supabase.com/blog/supabase-dynamic-functions
- Supabase Edge Functions: Introducing Background Tasks, Ephemeral Storage, and WebSockets, https://supabase.com/blog/edge-functions-background-tasks-websockets
- Supabase Back-end Logics | Database vs Edge Functions …, https://www.closefuture.io/blogs/supabase-database-vs-edge-functions
- Edge functions don’t explicitly state any limits such as timeouts, max body size, concurrency limits, etc · Issue #22002 - GitHub, https://github.com/supabase/supabase/issues/22002
- Limits | Supabase Docs, https://supabase.com/docs/guides/functions/limits
- Supabase edge functions are not production ready - Reddit, https://www.reddit.com/r/Supabase/comments/1fgu7bb/supabase_edge_functions_are_not_production_ready/
- Deciding between something like supabase and AWS for our pre-seed startup (we need database NOW) - Reddit, https://www.reddit.com/r/Supabase/comments/1cte5w8/deciding_between_something_like_supabase_and_aws/
- Poor performance with Edge Functions · supabase · Discussion #29301 - GitHub, https://github.com/orgs/supabase/discussions/29301
- Best Security Practices in Supabase: A Comprehensive Guide - Supadex, https://www.supadex.app/blog/best-security-practices-in-supabase-a-comprehensive-guide
- Best Practices for Securing and Scaling Supabase for Production Data Workloads | by firman brilian | Medium, https://medium.com/@firmanbrilian/best-practices-for-securing-and-scaling-supabase-for-production-data-workloads-4394aba9e868
- Pricing | Supabase Docs, https://supabase.com/docs/guides/functions/pricing
- Manage Edge Function Invocations usage | Supabase Docs, https://supabase.com/docs/guides/platform/manage-your-usage/edge-function-invocations
- Supabase vs AWS: Feature and Pricing Comparison (2025), https://www.bytebase.com/blog/supabase-vs-aws-pricing/
- Edge Functions Troubleshooting - Supabase Docs, https://supabase.com/docs/guides/functions/troubleshooting
- www.bytebase.com, https://www.bytebase.com/blog/supabase-vs-aws-pricing/#:~:text=Supabase%3A%20Deno%2Dbased%20edge%20functions,flexibility%2C%20and%20AWS%20ecosystem%20workflows.
- Are Supabase Edge Functions Scalable for Frequently Called Tasks? - Reddit, https://www.reddit.com/r/Supabase/comments/1hdr4sw/are_supabase_edge_functions_scalable_for/
- What I don’t like about Supabase | Build AI-Powered Software Agents with AntStack, https://www.antstack.com/blog/what-i-don-t-like-about-supabase/
- are supabase edge functions faster/better than Vercel edge functions Vercel edge… | Hacker News, https://news.ycombinator.com/item?id=38621849
- Edge functions vs workers : r/Supabase - Reddit, https://www.reddit.com/r/Supabase/comments/1ftxmld/edge_functions_vs_workers/
- Compare Cloudflare Workers vs. Supabase in 2025 - Slashdot, https://slashdot.org/software/comparison/Cloudflare-Workers-vs-Supabase/
- Developer Platform Pricing - Cloudflare Workers, https://workers.cloudflare.com/pricing
- Pricing - Workers - Cloudflare Docs, https://developers.cloudflare.com/workers/platform/pricing/
- supabase functions (not edge) - DEV Community, https://dev.to/tigawanna/supabase-functions-not-edge-2o1